'''
    服务之客户端简述：
        通过比对命令行和函数形参的个数进行请求对象的组建（命令行参数优先），通过异步方式发送请求，连接完成后输出结果并弹出系统

    客户端需要完成的操作：
        创建客户端对象 不需要连接回调函数
        创建发送请求函数 其中创建自定义接口的请求对象
        客户端对象 异步 发送请求对象且链接接收结果的回调函数
        接收回调函数以future对象作为参数调用result方法生成结果对象

    注意： MyHello.Request()  &  future.result().linked
          self.client.call_async(self.request).add_done_callback(self.accept_response) 
          创建的客户端对象     异步传入请求对象           结果回调
'''

import rclpy
from rclpy.node import Node
from my_interfaces.srv import MyHello
import sys


class Linker(Node):
    def __init__(self, name):
        super().__init__(name)
        self.client = self.create_client(MyHello, "Srv_LinkStr")             # 创建客户端（没有链接回调函数）
        self.request = MyHello.Request()                                     # 创建自定义请求对象
        self.get_logger().info("Node already start!")


    def send_request(self, *args):                              # 输入任意数量的参数进行连接
        prepare_link = []                                       # 待连接的元素列表
        for i in range(max(len(args), len(sys.argv) - 1)):      # 判断参数由命令行导入还是形参导入（命令行优先）
            if len(sys.argv) >= (i+2):
                prepare_link.append(sys.argv[i+1])
            else:
                prepare_link.append(args[i])
        self.request.link = prepare_link                        # 准备好的列表传递给请求对象

        while self.client.wait_for_service(1.0) == False:       # 等待服务器启动
            self.get_logger().info("Waiting for service...")

        self.client.call_async(self.request).add_done_callback(self.accept_response)    # 异步将请求压入堆栈并链接接收结果的回调函数


    # def send_request(self, pre='hello ', obj='czh'):
    #     while self.client.wait_for_service(1.0) == False:                               # 等待服务器启动
    #         self.get_logger().info("Waiting for service...")
    #     if len(sys.argv)>=2  and  sys.argv[1]:
    #         self.request.pre = sys.argv[1]
    #     else:
    #         self.request.pre = pre
    #     if len(sys.argv)>=3  and  sys.argv[2]:
    #         self.request.obj = sys.argv[2]
    #     else:
    #         self.request.obj = obj
    #     self.client.call_async(self.request).add_done_callback(self.accept_response)    # 异步将请求压入堆栈并链接接收结果的回调函数
    
    def accept_response(self, future):                                                  # 结果回调函数以 future 对象作为参数
        self.response = future.result()                                                 # 调用方法获取结果对象
        self.get_logger().info("Get answer: %s" % self.response.linked)                 # 获取结果对象的属性值
        exit()


def main(args=None):
    rclpy.init()
    node = Linker("linker_client")
    node.send_request("Hello", "czh", "lee")          # 调用函数发送请求
    # node.send_request()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()